import numpy as np
from sklearn import datasets
from sklearn import preprocessing
import pandas as pd
from scipy.stats import chi2_contingency
from matplotlib import pyplot as plt
import seaborn as sns


def yichang_test(df):
    mean = df.mean()
    std = df.std()
    down_data = mean - 3 * std
    up_data = mean + 3 * std
    err = []
    for i in range(len(df)):
        if df.loc[i]['花萼宽度'] < down_data.array[1] or df.loc[i]['花萼宽度'] > up_data.array[1]:
            err.append(df.loc[i]['花萼宽度'])
    print(f"花萼宽度异常数据个数：{len(err)}")
    print(err)


def min_max_normalization(df):
    min = df.min()
    max = df.max()
    min_max_data = (df - min) / (max - min)
    return min_max_data

def caculate_corr(df):
    return df.corr()


# 1
Dataset = datasets.load_iris()
print("1、\ndata:\n")
print(Dataset.data[:5])
print("\ntarget:\n")
print(Dataset.target[-5:])
print("\nfeature_names:\n")
print(Dataset.feature_names)
print("\nDESCR:\n")
print(Dataset.DESCR)

# 2
df = pd.DataFrame(Dataset.data, columns=Dataset.feature_names)
df.columns = ['花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度']
print(df.head())

# 3
yichang_test(df)

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
fig, ax1 = plt.subplots()
ax1.hist(df['花萼宽度'], edgecolor='black', label='直方图')
ax1.set_xlabel('花萼宽度')
ax1.set_ylabel('频数', color='b')
ax1.tick_params('y', colors='b')
ax1.legend(loc='upper left')
ax2 = ax1.twinx()
sns.kdeplot(df['花萼宽度'], ax=ax2, color='r', label='核密度图')
ax2.set_ylabel('密度', color='r')
ax2.tick_params('y', colors='r')
plt.title('花萼宽度直方图及核密度图')
handles1, labels1 = ax1.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(handles1 + handles2, labels1 + labels2, loc='upper left')
plt.savefig('花萼宽度直方图及核密度图.jpg')
plt.show()


# 4
Q1 = df['花萼宽度'].quantile(0.25)
Q3 = df['花萼宽度'].quantile(0.75)
delta = Q3 - Q1
lower_bound = Q1 - 1.5 * delta
upper_bound = Q3 + 1.5 * delta
err_data = df[(df['花萼宽度'] < lower_bound) | (df['花萼宽度'] > upper_bound)]
print("异常数据值：")
print(err_data['花萼宽度'])

# 5
min_max_data = min_max_normalization(df['花萼宽度'])
print(min_max_data)

# 6
Scaler = preprocessing.StandardScaler()
z_score_data = Scaler.fit_transform(df['花萼宽度'].values.reshape(-1, 1))
print(z_score_data)

# 7
data_list = [['110kV', 83, 43],
             ['220kV', 45, 52],
             ['500kV', 55, 54],
             ['1100kV', 5.7, 40]]
accident_data = pd.DataFrame(data_list, columns=['电压', '线路总长度', '故障数'])
chi2, p, dof, expected = chi2_contingency(accident_data.values.T[1:3].tolist())
print(f'卡方统计量：{chi2}')
print(f'P值：{p}')
if p < 0.05:
    print("经过卡方检验，跳闸事故数是否与线路总长度有关")
else:
    print("经过卡方检验，跳闸事故数是否与线路总长度无关")

# 8
corr_mat = caculate_corr(df)
print(corr_mat)